package de.bildung.koblenz.homeswitch.tasks;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Looper;
import android.util.Log;

public class DiscoveryTask extends AsyncTask<String, Integer, String> {
	
	private static final int DISCOVER_PORT = 54038;
	
	private IDiscoveryResult callback;
	
	private ProgressDialog dialog;
	
	public interface IDiscoveryResult {
		public void discoveryFinished(String ip, String port);
	}
	
	public DiscoveryTask(Context context, IDiscoveryResult onResult) {
		super();
		
		this.callback = onResult;
		this.dialog = new ProgressDialog(context);
		dialog.setCancelable(false);
		dialog.setTitle("Suche Server");
	}
	
	

	@Override
	protected void onPostExecute(String result) {
		super.onPostExecute(result);
		dialog.cancel();
	}



	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		dialog.show();
	}



	@Override
	protected String doInBackground(String... params) {
		try {
			ServerSocket mSocket;
			mSocket = new ServerSocket();
			mSocket.bind(null);
			
			DatagramSocket broadcast = new DatagramSocket();
			broadcast.setBroadcast(true);
			
			ByteBuffer data = ByteBuffer.allocate(4);
			data.putInt(mSocket.getLocalPort());
			
			Socket client;
			byte[] buffer = new byte[50];
			
			DatagramPacket packet = new DatagramPacket(data.array(), data.capacity(),
				InetAddress.getByName("255.255.255.255"), DISCOVER_PORT);
			broadcast.send(packet);
			
			mSocket.setSoTimeout(10000);
			client = mSocket.accept();
			client.getInputStream().read(buffer);
			Integer port = (int) ByteBuffer.wrap(buffer).order(ByteOrder.BIG_ENDIAN).getShort();
			port += 1<<16;
			String remoteSocket = client.getRemoteSocketAddress().toString().replaceAll("/", "");
			remoteSocket = remoteSocket.substring(0, remoteSocket.indexOf(":"));
			this.callback.discoveryFinished(remoteSocket, String.valueOf(port));
		} catch (Exception e) {
			Log.e(e.getMessage(), e.getStackTrace().toString());
			this.callback.discoveryFinished(null, null);
		}
		return null;
	}

}
